#include "ConeMesh.h"
#include "VertexList.h"
#include "LineList.h"

#define _USE_MATH_DEFINES
#include "math.h"

ConeMesh::ConeMesh(DAEFloat3 position, DAEFloat3 direction, float angle, float height, unsigned int heightSegments, unsigned int sides,DAEFloat3 color)
	:m_Position(position),
m_Direction(direction),
m_Angle(angle),
m_Height(height),
m_HeightSegments(heightSegments),
m_Sides(sides),
m_Color(color),
m_pMesh(NULL)
{
	vector<SemanticDescriptor> semantics;
	
	SemanticDescriptor sdpos;
	sdpos.dataType = VL_FLOAT;
	sdpos.nrOfElements = 3;
	sdpos.semantic = POSITION;
	sdpos.index =0;

	SemanticDescriptor sdcolor;
	sdcolor.dataType = VL_FLOAT;
	sdcolor.nrOfElements = 3;
	sdcolor.semantic = COLOR;
	sdcolor.index = 0;

	semantics.push_back(sdpos);
	semantics.push_back(sdcolor);
	int nrOfVertices = (heightSegments-1)*sides + 1;
	VertexList* vertexList = new VertexList(nrOfVertices,semantics,true);
	int nrOfLines =sides * (2*heightSegments-1);
	LineList* lineList = new LineList(nrOfLines);

	vertexList->AddVertexData(0,POSITION,&m_Position);

	m_Direction.Normalize();

	DAEFloat3 xVector,yVector;
	
	m_Direction.CreatePerpendicularVector(xVector);
	xVector.CrossAndNormalize(yVector,m_Direction);
	int vertexIndex = 1;
	for ( int segment = 1 ; segment < (int)heightSegments; ++segment)
	{
		for ( int i = 0; i < (int)sides; ++i)
		{
			DAEFloat3 center;
			float distance = (m_Height * segment)/(m_HeightSegments-1);
			m_Position.Add(center,distance,m_Direction);

			float radius = distance * tan( m_Angle);
			float circleAngle = (float)((2.0f * i * M_PI)/(sides-1));

			float xcoord = radius * cos ( circleAngle );
			float ycoord = radius * sin ( circleAngle );
		
			DAEFloat3 vertex;
			center.Add(vertex, xcoord, xVector);
			vertex.Add(vertex, ycoord, yVector);

			vertexList->AddVertexData(vertexIndex++,POSITION,&vertex);
		}
	}

	for ( int i = 0; i < (int)sides; ++i )
	{
		lineList->AddIndexedLine(i+1,0);
	}

	for ( int segment = 1; segment < (int)(heightSegments-1) ; ++segment )
	{
		for (int i = 0; i < (int)sides; ++i)
		{
			int index = i + (segment-1)*sides + 1;
			int index2 = index+1;
			if (i == (sides-1) )
				index2 = (segment-1)*sides+1;
			lineList->AddIndexedLine(index,index2);
			lineList->AddIndexedLine(index,index+sides);
		}
	}

	for ( int i = 0; i < (int)sides; ++i ){
		int index = i + (heightSegments-1) *sides +1;
		int index2  =index +1;
		if ( i == (sides-1) )
			index2 = (heightSegments-1) * sides + 1;
		lineList->AddIndexedLine(index,index2);
	}
	vertexList->FillSemantic(COLOR, &m_Color);
	m_pMesh = new ObjMesh(vertexList,lineList);
}


ConeMesh::~ConeMesh(void)
{
	delete m_pMesh;
}
